浅谈 float 数组初始化

您所在的位置:网站首页 c 数组赋值0 浅谈 float 数组初始化

浅谈 float 数组初始化

2023-04-02 03:57| 来源: 网络整理| 查看: 265

需求

想给整个 float 数组所有元素赋为同一个值。我们关注结果是否正确,也关注性能。

错误写法

一种常见的错误写法是:

size_t len = 1000000; float* data = (float*)malloc(len * sizeof(float)); memset(data, 0, len * sizeof(float));

这里有两个问题:

1. memset一个float数组为0,很多主流编译器结果确实是0,但不能确保总是0

2. 如果memset的值不是0,比如3.14,那么基本上不可能得到正确结果。

折中写法

有人建议逐元素赋值:

size_t len = 1000000; float* data = (float*)malloc(len * sizeof(float)); float init_value = 0; for (size_t i=0; i=C++17,暂不考虑)和std::fill_n,于是考虑这样写:

#include // 头文件 size_t len = 1000000; float* data = (float*)malloc(len * sizeof(float)); std::fill_n(data, len, 3.14); 基于arm neon实现

在x86 64平台,目测编译器自动实现了SIMD优化,就不班门弄斧了。在android arm32/64平台,手动基于NEON指令实现类似于std::fill_n的函数,实测有明显加速效果。具体实现代码:

static void array_fill_f32_asimd(float* data, size_t len, float value) { size_t done = 0; #if __ARM_NEON size_t step = 4; size_t vec_size = len - len % step; float32x4_t v1 = vdupq_n_f32(value); for (size_t i=0; i

可以看到,在release模式下,armv8平台的std::fill_n和基于neon的实现一样快;在armv7 release模式,以及armv8和armv7的debug模式下,基于neon的实现速度优势明显,远超逐元素赋值和std::fill_n。

结论

在给float类型数组所有元素赋予同一个初始值的时候:

不应该用memset,尽管memset设定为0时,通常得到正确结果;但设定为其他值不会得到正确结果在x86平台,编译器能够自动的SIMD优化,逐元素赋值的写法或`std::fill()`都OK逐元素赋值的效率并不高,可以考虑用`std::fill_n()`替代如果要提高Debug模式下的性能,armv7/v8平台下,`std::fill_n()`仍不是最佳选择,手写neon更快。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3